local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
local bb,i = {},0 for i=1,#b do bb[b:sub(i,i)]=i-1 end
function encdate(y,m,d) return (tonumber(d)-1)+(tonumber(m)-1)*31+(tonumber(y)-8)*372 end
function decdate(sum) return math.floor(sum/372)+8, math.floor(sum %372/31)+1, sum%31+1 end
function enc(sums) local r = ""; for _, v in pairs(sums) do r = r..b:sub(math.floor(v/64)+1,math.floor(v/64)+1)..b:sub(v%64+1,v%64+1) end return r end
function dec(str) 
	if(#str==2) then return bb[str:sub(1,1)]*64+bb[str:sub(2,2)] end
	local sums = {}
	for i=1,#str,2 do
		local sum=bb[str:sub(i,i)]*64+bb[str:sub(i+1,i+1)]
		table.insert(sums,sum) 
	end
	return sums 
end

local function urlencode(obj)
	local currentIndex = 1;
	local charArray = {}
	while currentIndex <= #obj do
		local char = string.byte(obj, currentIndex);
		charArray[currentIndex] = char
		currentIndex = currentIndex + 1
	end
	local converchar = "";
	for _, char in ipairs(charArray) do
		converchar = converchar..string.format("%%%X", char)
	end
	return converchar;
end

local archs = {1176,1177,1178,1017,2097,556,557,558,705,621,6,8,10,11,12,13,545,964,891,889,890,892,546,2716,1180,973,974,975,976,503,504,505,506,507,508,31,238,515,397,1157,218,166,1308,3776,1717,2085,2086,2087,2088,2089,4476,4477,4478,3839,3841,3842,3844,3876,3778,4516,2154,4521,4297,490,494,500,1817,2046,2044,2045,493,495,1871,1867,1862,1868,2150,1860,733,116,734,735,131,134,135,522,523,1009,1008,1007,947,}

function encbase(class, race, sex)
	local _,_,y,m,d = os.date("%y-%m-%d"):find("(%d+)-(%d+)-(%d+)")
	return enc({encdate(y,m,d)})..string.format("%X",class)..string.format("%X",race)..sex
end

function trim(s)
	local n,m,l,v = s:sub(1,s:find("%-")-1), s:sub(s:find("%^")+3,s:find("%^")+4)..s:sub(s:find("%^")+6),0,0
	local x = string.byte(n, 1) >= 224 and {3,3} or {1,2}
	for y=x[1],#n,x[2] do
		l,v = l+1,string.byte(n,y)+string.byte(m,l+1)
		s=s..b:sub(v%64+1,v%64+1)
	end
	return s;
end

local io = require("io")
local http = require("socket.http")
local ltn12 = require("ltn12")

function dohttp(_url, all)
	local sink = {}
	local r, c = socket.http.request {
	    url = _url,
	    sink = ltn12.sink.table(sink),
	    headers = { ["User-Agent"] = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)" }
	}
	if(c~=200) then
		print("ERROR");
		return nil;
	end
	local xml = table.concat(sink,"")
	--print(xml));
	if(string.find(xml, "<errorhtml") or string.find(xml, "<category/>") or not string.find(xml, "</achievements>")) then
		print("ERROR");
		return nil;
	end

	string.gsub(xml, "dateCompleted=\"(%d+)-(%d+)-(%d+)T[0-9:%+%-]*\" [^>]* id=\"(%d+)\" [^>]* title=\"([^>]*)\"[/]?>", function(y,m,d,id,title)
		id=tonumber(id)
		all[id] = encdate(y-2000,m,d)
		--print(y.."-"..m.."-"..d..", id="..id..", title="..title..", all="..all[id]) 
	end);

end

print("Input armory link: http://.../character-sheet.xml?r=<realm>&cn=<player>")
io.write("> ")
url = io.read()
--url = "http://tw.wowarmory.com/character-sheet.xml?r=%E8%81%96%E5%85%89%E4%B9%8B%E9%A1%98&cn=%E4%B8%89%E6%9C%88%E5%8D%81%E4%BA%8C"
_, _, realm, player = string.find(url, "http://.*%.wowarmory%.com/character%-sheet%.xml%?r=(.*)&cn=(.*)")
--realm = urlencode("聖光之願")
--player = urlencode("三月十二")

all = {}
function dobase(_url)
	local sink = {}
	local r, c = socket.http.request {
	    url = _url,
	    sink = ltn12.sink.table(sink),
	    headers = { 
	        ["User-Agent"] = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)",
		["Accept-Language"] = "zh-tw,zh;q=0.5" 
	    }
	}
	local xml = table.concat(sink, "")
	local _,_,base = xml:find("<characterInfo>%s*<character ([^>]*)[/]?>")
	local _,_,classId = base:find("classId=\"(%d*)\"")
	local _,_,genderId = base:find("genderId=\"(%d*)\"")
	local _,_,raceId = base:find("raceId=\"(%d*)\"")
	local _,_,nameutf8 = base:find("name=\"([^\"]*)\"")
	local _,_,realmutf8 = base:find("realm=\"([^\"]*)\"")
	return nameutf8.."-"..realmutf8.."^"..encbase(tonumber(classId), tonumber(raceId), tonumber(genderId))
end

base = dobase(url)
--print(base)
io.write("now getting achievements, please wait.")
cats = {92,96,95,168,169,201}
for i=1, #cats do
	dohttp("http://tw.wowarmory.com/character-achievements.xml?r="..realm.."&n="..player.."&c="..cats[i], all);
	io.write(".")
end
io.write("\n")
tmp = {}
for _, v in pairs(archs) do
	if(all[v]) then
		local y,m,d = decdate(all[v])
		--print(string.format("id=%d, date=%d-%d-%d, sum=%d", v, y, m, d, all[v]));
		table.insert(tmp, all[v])
	else
		--print(string.format("id=%d, not complete", v));
		table.insert(tmp, 0);
	end
end
print("The characters identity is : ")
print("#"..base..enc(tmp).."#")
print()
print("It is also appended to file 'Armory.txt'.")
print()
file = io.open("Armory.txt", "a+")
file:write("{\n\t--"..url.."\n\t\""..trim(base..enc(tmp)).."\",\n\t\"這裡輸入大致情況\",\n\t\"這裡是證據網頁\",\n\t\"這裡是舉報人\",\n},\n");